package com.crealth.crmserver;

import java.net.InetSocketAddress;
import java.util.Iterator;
import java.util.List;

import org.apache.log4j.Logger;
import org.apache.mina.core.service.IoHandlerAdapter;
import org.apache.mina.core.session.IdleStatus;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.transport.socket.SocketSessionConfig;

import com.alibaba.fastjson.JSONObject;
import com.crealth.ConstantDefine;
import com.crealth.db.CompanyDb;
import com.crealth.db.UserDb;
import com.crealth.handler.RequestMsgQueue;
import com.crealth.handler.ResponseMsgQueue;
import com.crealth.handler.UserHandler;
import com.crealth.model.CompanyModel;
import com.crealth.model.UserModel;
import com.crealth.msg.NetMessageData;

public class CRMServerHandler extends IoHandlerAdapter {	
	private static final Logger logger = Logger.getLogger("running_log");
	private static Logger errorLog = Logger.getLogger("error_log");
	//private static final Logger clientLog = Logger.getLogger("client_connect");
	
	@Override  
    public void exceptionCaught(IoSession session, Throwable cause) throws Exception {  
        //logger.error("ClientHandler exceptionCaught ", cause);
    }  
  
    @Override  
    public void messageReceived(IoSession session, Object message)throws Exception {  
    	NetMessageData apiMsg = (NetMessageData)message;
    	if (apiMsg == null) {
    		return;
    	}
    	String strMsgBody = apiMsg.getMsgBody();
    	if (strMsgBody == null || strMsgBody.length() < 1) {
    		errorLog.error("receive msg is null or empty");
    		return;
    	}
    	JSONObject msgJson = apiMsg.getRevDataMsgJson();
		if (msgJson == null) {
			errorLog.error("not right json format: " + strMsgBody);
			return;
		}
		String type = msgJson.getString("Type");
		NetMessageData resData = null;
		int cmd = apiMsg.getMsgCmd();		
		//String revInfo = "rev cmd: "+cmd;
		if (type != null && type.equals("fromShowClient")) {			
			return;
		}
		else if (NetMessageData.Net_REV_LOGIN == cmd) {
			resData = UserHandler.login(session, apiMsg);
		}
		else if (NetMessageData.Net_ReConnect == cmd) {
			resData = UserHandler.reConnect(session, apiMsg);
		}
		else if (NetMessageData.Net_Obtain_Version == cmd) {
			resData = UserHandler.obtainLastestVersion(apiMsg);
		}
		else if (NetMessageData.Net_Heart_Beat == cmd) {
			resData = UserHandler.onHeartBeat(apiMsg);
		}
		else if (cmd > 0) {
			if (!msgJson.containsKey("id")) {
				errorLog.error("receive message error, not id key");
				return;
			}
			int userID = msgJson.getIntValue("id");
			if (userID <= 0) {
				errorLog.error("cmd: "+cmd+" user ID error <= 0");
				return;
			}
			//revInfo = "rev userID: " + userID + "  cmd: "+cmd;
			apiMsg.setUserID(userID);
			RequestMsgQueue.addMsgToQueue(apiMsg);
		}
		//logger.info(revInfo);
		
		if (resData != null) {
			//logger.info("send cmd:" + cmd);
			resData.setMsgCmd(cmd);
			sendToSession(session, resData);				
		}
    }
  
    @Override  
    public void messageSent(IoSession session, Object message) throws Exception {  
         
    }
    
    public static String getClientIP(IoSession session) {
    	String clientIP = ((InetSocketAddress)session.getRemoteAddress()).getAddress().getHostAddress();
    	
    	return clientIP;
    }
  
    @Override  
    public void sessionClosed(IoSession session) throws Exception {
    	if (SessionManager.boradShowClientSessions.contains(session)) {
    		SessionManager.boradShowClientSessions.remove(session);
    	}
    	else {
    		
    	}
    	String clientIP = getClientIP(session);
    	logger.info(clientIP+" sessionClosed");
    }  
  
    @Override  
    public void sessionCreated(IoSession session) throws Exception {  
    	SocketSessionConfig cfg = (SocketSessionConfig)session.getConfig();  
        cfg.setReceiveBufferSize(2*1024*1024);  
        cfg.setReadBufferSize(2*1024*1024);  
        cfg.setKeepAlive(true);  
        cfg.setSoLinger(0); //这个是根本解决问题的设置
        
    	//String clientIP = ((InetSocketAddress)session.getRemoteAddress()).getAddress().getHostAddress();
    	//logger.info(clientIP+" sessionCreated");
    }  
  
    @Override  
    public void sessionIdle(IoSession session, IdleStatus status) throws Exception {  
    	
    }  
  
    @Override  
    public void sessionOpened(IoSession session) throws Exception {  
    	//String clientIP = ((InetSocketAddress)session.getRemoteAddress()).getAddress().getHostAddress();
    	//logger.info(clientIP+" sessionOpened");
    	
    	SessionManager.addBoardClientSession(session);
    	/*
    	JSONObject sendJson = ApiMessageHandler.useSimCardStat.toJsonObject();
		String sendBody = sendJson.toJSONString();
		ApiServerMessage sendMsg = new ApiServerMessage();
		sendMsg.setMsgBodyLen(sendBody.length()+4);
		sendMsg.setMsgType(ApiServerMessage.Net_Use_SimCard);
		sendMsg.setMsgBody(sendBody);
		if (session != null && session.isConnected() ) {
	        session.write(sendMsg);
		}
		*/
    }
    
    private void sendToSession(IoSession session, NetMessageData sendMsg) {
    	String sendBody = sendMsg.getMsgBody();
    	if (sendMsg == null || sendBody.length() == 0) {
    		return;
    	}
    	
    	sendMsg.setMsgBodyLen(sendBody.length()+4);
    	session.write(sendMsg);
    }
    
    public static void sendMsgToClients(String sendBody, int cmd) {
    	if (cmd < 0) {
    		return;
    	}
    	NetMessageData sendMsg = new NetMessageData();
		sendMsg.setMsgBodyLen(sendBody.length()+4);
		sendMsg.setMsgCmd(cmd);
		sendMsg.setMsgBody(sendBody);
		sendMsgToClients(sendMsg);
    }
    
    public static void sendMsgToClients(NetMessageData msgObj) {
    	if (msgObj == null) {
    		return;
    	}
    	
    	Iterator<IoSession> setIt = SessionManager.boradShowClientSessions.iterator();
    	while(setIt.hasNext()) {
    		IoSession session = setIt.next();
    		if (session != null && session.isConnected() ) {
    	        session.write(msgObj);
    		}
    	}
    }
    
    public static void sendMsgToLeader(int cmd, UserModel user, NetMessageData sendMsg) {
    	Integer leaderID = user.getLeaderID();
		if (leaderID != null && leaderID > 0 && leaderID != user.getId()) {
			ResponseMsgQueue.addMsgToQueue(cmd, leaderID, sendMsg);
		}
    }
    
    private static void boradMsgToCompany(int opUser, int companyID, NetMessageData sendMsg) {
    	List<UserModel> userls = UserDb.selectBranchUser(companyID);
    	int cmd = sendMsg.getMsgCmd();
    	for (UserModel curUser : userls) {
    		if (curUser.getId() == opUser || 
    			curUser.getPosition() >= ConstantDefine.Head_Manager || 
    			curUser.getPosition() == ConstantDefine.Installmenter || 
    			curUser.getPosition() == ConstantDefine.InstallDpmMGR  ) {
    			continue;
    		}
    		ResponseMsgQueue.addMsgToQueue(cmd, curUser.getId(), sendMsg);
    	}
    }
    
    public static void boradMsgToCompany(int opUser, String strCityName, NetMessageData sendMsg) {
    	List<CompanyModel> companyls = CompanyDb.selectAllCompany();
    	for (CompanyModel curCompany : companyls) {
    		if (curCompany.getBelongCompany().getCityName().equals(strCityName) ) {
    			boradMsgToCompany(opUser, curCompany.getId(), sendMsg);
    		}
    	}
    }
    
	
}
